﻿/* Projections methods */
jsoq_regEnumMethod("toArray", function() {
    this.reset();
    var res = [];
    while (this.next())
        res.push(this.current);
    return res;
});

jsoq_regEnumMethod("contains", function(clause) {
    this.reset();
    var where = baseEnum_getClause(clause);
    if (!where) return this.next();
    while (this.next()) {
        if (where(this.current))
            return true;
    }
    return false;
});

jsoq_regEnumMethod("each", function(iteratorFunc, repeat) {
    repeat = repeat || 1;
    iteratorFunc = baseEnum_getClause(iteratorFunc);
    while (repeat-- > 0) {
        this.reset();
        while (this.next())
            iteratorFunc(this.current);
    }
});

jsoq_regEnumMethod("first", function(clause) {
    this.reset();
    clause = baseEnum_getClause(clause);
    if (!clause) {
        this.next();
        return this.current;
    }
    while (this.next()) {
        if (clause(this.current)) {
            return this.current;
        }
    }
    return null;
});

jsoq_regEnumMethod("firstOrDefault", function(clause, defaultIfEmpty) {
    var first;
    return (first = this.first(clause)) ? first : defaultIfEmpty;
});

jsoq_regEnumMethod("last", function(clause) {
    var result;
    this.reset();
    clause = baseEnum_getClause(clause);
    if (!clause) {
        while (this.next())
            result = this.current;

    }
    else {
        while (this.next()) {
            if (clause(this.current))
                result = this.current;
        }
    }
    return result;
});

jsoq_regEnumMethod("lastOrDefault", function(clause, defaultIfEmpty) {
    var last;
    return (last = this.last(clause)) ? last : defaultIfEmpty;
});

jsoq_regEnumMethod("sum", function(clause) {
    var result = 0, itemValue = 0;
    this.reset();
    clause = baseEnum_getClause(clause, default_clauses_returnCurrent);
    while (this.next())
        result += (itemValue = clause(this.current)) ? itemValue : 0;
    return result;
});

jsoq_regEnumMethod("average", function(clause) {
    var sum = 0, count = 0, itemValue = 0;
    clause = baseEnum_getClause(clause, default_clauses_returnCurrent);
    this.reset();
    while (this.next()) {
        itemValue = clause(this.current);
        if (itemValue !== null) {
            sum += itemValue;
            count++;
        }
    }
    return count === 0 ? 0 : sum / count;
});

jsoq_regEnumMethod("avg", function(clause) { return this.average(clause); });

jsoq_regEnumMethod("max", function(clause) {
    var result;
    this.reset();
    if (!this.next()) return 0;
    clause = baseEnum_getClause(clause, default_clauses_returnCurrent);
    result = clause(this.current);
    while (this.next())
        result = Math.max(result, clause(this.current));
    return result;
});

jsoq_regEnumMethod("min", function(clause) {
    var result;
    this.reset();
    if (!this.next()) return 0;
    clause = baseEnum_getClause(clause, default_clauses_returnCurrent);
    result = clause(this.current);
    while (this.next())
        result = Math.min(result, clause(this.current));
    return result
});

jsoq_regEnumMethod("count", function(condiction) {
    var result = 0;
    condiction = baseEnum_getClause(condiction, null);
    this.reset();
    if (!condiction) {
        for (; this.next(); result++) { }
    } else {
        while (this.next()) {
            if (condiction(this.current))
                result++;
        }
    }
    return result;
});

